//
// Created by ziya on 2023/11/28.
//

#include "../include/gdt.h"
#include "../include/string.h"
#include "../include/mm.h"

extern int64 kernel_space_base_addr;

gdtr_data_t gdtr_data;

tss_t g_tss;

void install_tss(uint64_t base) {
    tss_descriptor_t* descriptor = gdtr_data.base + TSS_INDEX * 8;

    descriptor->limit_low = 104;
    descriptor->base_low = base & 0xFFFF;
    descriptor->base_mid = (base >> 16) & 0xFF;
    descriptor->flags1 = 0x89;
    descriptor->limit_high_and_flags2 = 0;
    descriptor->base_high = (base >> 24) & 0xFF;
    descriptor->base_upper = base >> 32;
    descriptor->reserved = 0;

    uint16_t tss_selector = TSS_INDEX << 3;
    __asm__ ("ltr %0" : : "r"(tss_selector));
}

void gdt_init() {
    asm volatile ("sgdt gdtr_data;");

    memset(&g_tss, 0, sizeof(tss_t));
    g_tss.rsp0 = kmalloc(4096) + PAGE_SIZE;
    g_tss.ist1 = kmalloc(4096) + PAGE_SIZE;
    g_tss.ist2 = kmalloc(4096) + PAGE_SIZE;

    install_tss((uint64_t)&g_tss);
}